由一段js正则式想到

今天找JS的json函数,发现一段代码:

1
2
3
4
5
6
7
8
9
parse: function (text) {
try {
return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
eval('(' + text + ')');
} catch (e) {
return false;
}
}

详细的代码可以见这里
应该是很老的代码了,但是真是搞不清这里的含义

/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/

中间 Eaeflnr-u 这一段的意思是?为什么要这样去判断是否是json的格式呢?

好奇没有想明白,但是用这一段来判断确实是错误的,比如输入’{“key”:Math.PI}’时候这里会parse不到正确的json。

douglascrockford 后面改进的JSON.js以及JSON2.js都是对此parse失败的,同样json.org官方提供的两个javascript的json库里clarinet.js也是parse失败的。。。(但,stringfy({“key”:Math.PI})是正确)

难道这个json不应该是被parse正确的吗?

附上CrockFord 改进的版本,作者改进了对应的正则表达式,使用这样的正则表达式的初衷在注释里面可以看到一些,呵呵。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.